﻿using AntdUI;
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using ImportPlcPointPosition.Controls.Base;
using ImportPlcPointPosition.Extensions;
using ImportPlcPointPosition.Forms;
using ImportPlcPointPosition.Models;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZR.Model.Models.ProductionControl;

namespace ImportPlcPointPosition.Controls.Pages {
    public partial class CollectDataConfigPage : BaseUserControl {

        #region Fields

        private BindingList<CksVirtualTable> Source = new BindingList<CksVirtualTable>();
        private BindingList<CksVirtualColumn> FieldSource = new BindingList<CksVirtualColumn>();
        private BindingList<CksPlcActions> ActionsSource = new BindingList<CksPlcActions>();
        private CksVirtualTable Context = null;

        #endregion

        public CollectDataConfigPage() {
            InitializeComponent();
            this.Load += CollectDataConfigPage_Load;
        }

        #region Methods

        /// <summary>
        /// 初始化表格1（虚拟表列表）
        /// </summary>
        private void InitTable() {
            table1.EditMode = TEditMode.None;
            table1.Columns = new ColumnCollection() {
                new Column("TableName", "表名").SetMaxWidth("100%").SetEllipsis().SetAlign(ColumnAlign.Left),
            };
            //table1.Columns.Add(new Column("Notes", "备注"));

            table1.Bordered = true;
            table1.EnableHeaderResizing = true;
            table1.EmptyHeader = true;
            table1.Gap = 6;
            table1.VisibleHeader = false;

            table1.CellClick += Table1_CellClick;
        }

        /// <summary>
        /// 初始化表格2（虚拟表字段列表）
        /// </summary>
        private void InitFieldTable() {
            table2.EditMode = TEditMode.Click;
            table2.Columns = new ColumnCollection() {
                new ColumnCheck(nameof(CksVirtualColumn.IsCheck)).SetAlign().SetFixed(),
                new Column("Sequence", "顺序").SetAlign(),
                new Column("ColumnName", "字段名称").SetAlign(),
                new Column("Notes", "字段描述").SetAlign(),
                new ColumnCheck("IsPrimary", "是否主码字段").SetAlign(),
                new ColumnCheck("IsResult", "是否结果字段").SetAlign(),
                new ColumnCheck("IsCycleTime", "是否节拍字段").SetAlign(),
                new ColumnCheck("IsBatchCode", "是否批次字段").SetAlign(),
                new ColumnCheck("IsDisplay", "是否显示(Web)").SetAlign(),
                new Column("Width", "显示宽度(Web)").SetAlign(),
                new Column("DataId", "数据编号").SetAlign().SetWidth("100"),
            };
            //table2.Columns.Add(new Column("LanguageKey", "翻译Key"));

            table2.Bordered = true;
            table2.EnableHeaderResizing = true;
            table2.EmptyHeader = true;
            table2.Gap = 6;
            table2.VisibleHeader = true;
            table2.CellBeginEditInputStyle += (s, e) => {
                e.Input.SelectAll();
            };

            table2.CellClick += (s, e) => {
                var config = e.Record as CksVirtualColumn;
                if (e.Button == MouseButtons.Right)
                    ShowRightButton(table2, config);
            };
            table2.CellClick += Table2_CellClick;
        }

        /// <summary>
        /// 初始化表格3（动作列表）
        /// </summary>
        private void InitActionTable() {
            table3.EditMode = TEditMode.Click;
            table3.Columns = new ColumnCollection() {
                //new Column("PlcId", "PlcID").SetAlign(),
                new Column("PlcIdCellText", "PLC").SetAlign(),
                new Column("ActionId", "动作编号").SetAlign(),
                new Column("ActionKey", "动作Key").SetMaxWidth("80").SetEllipsis().SetAlign(),
                //new Column("ReadDB", "ReadDB").SetAlign(),
                //new Column("WriteDB", "WriteDB").SetAlign(), 
                new Column("DBblockCellText", "ReadDB").SetAlign(),
                new Column("DBblockCellText", "WriteDB").SetAlign(),
            };

            table3.Bordered = true;
            table3.EnableHeaderResizing = true;
            table3.EmptyHeader = true;
            table3.Gap = 6;
            table3.VisibleHeader = true;
            table3.CellBeginEditInputStyle += (s, e) => {
                e.Input.SelectAll();
            };

            table3.CellClick += (s, e) => {
                var config = e.Record as CksPlcActions;
                if (e.Button == MouseButtons.Right)
                    ShowRightButton(table3, config);
            };

        }

        private void ShowRightButton(Table table, object data) {
            List<IContextMenuStripItem> menus = new List<IContextMenuStripItem>();
            menus.Add(new ContextMenuStripItem("删除") {
                ID = "delete",
                Fore = Color.Red,
                IconSvg = "DeleteOutlined"
            });
            menus.Add(new ContextMenuStripItem("复制") {
                ID = "copy",
                Fore = Color.Blue,
                IconSvg = "CopyOutlined"
            });
            AntdUI.ContextMenuStrip.open(table, OnClickRightMenu(data), menus.ToArray());
        }

        private void LoadCheckData(CksVirtualTable context) {
            FieldSource.Clear();
            ActionsSource.Clear();
            if (context == null)
                return;
            //加载虚拟表字段
            LoadColumnData(context.Id);
            //加载绑定动作
            LoadPlcActions(context.Id);
        }

        private void LoadColumnData(int tableId) {
            FieldSource.Clear();
            var db = SqlSugarHelper.MesDB;
            var lst = db.Queryable<CksVirtualColumn>().Where(a => a.TableId == tableId).OrderBy(a => a.Sequence).ToList();
            FieldSource.AddRange(lst);
            this.table2.Binding(FieldSource);
        }

        private void LoadPlcActions(int tableId) {
            ActionsSource.Clear();
            var db = SqlSugarHelper.MesDB;
            var lst = db.Queryable<CksPlcActions>().Where(a => a.ActionType == 1 && a.BusinessId == tableId).OrderBy(a => a.Id).ToList();
            foreach (var item in lst) {
                ActionsSource.Add(item);
            }
            this.table3.Binding(ActionsSource);
        }

        /// <summary>
        /// 刷新数据
        /// </summary>
        public void ReflushData() {
            string search = txtSearch.Text;
            Source.Clear();
            var db = SqlSugarHelper.MesDB;
            var lst = db.Queryable<CksVirtualTable>()
                   .WhereIF(!search.IsNullOrEmpty(), (a) => a.TableName.Contains(search))
                   .OrderBy(a => a.Sequence)
                   .ToList();
            foreach (var item in lst) {
                Source.Add(item);
            }
            this.table1.Binding(Source);
            if (Source.Count > 0) {
                if (table1.SelectedIndex < 1) {
                    table1.SelectedIndex = 1;
                    Context = Source[0];
                    LoadCheckData(Context);
                } else {
                    Context = Source[table1.SelectedIndex - 1];
                    LoadCheckData(Context);
                }
            } else {
                //没有数据清理另外两个表
                LoadCheckData(null);
            }
        }

        #endregion


        #region Events

        private void CollectDataConfigPage_Load(object sender, EventArgs e) {
            InitTable();
            InitFieldTable();
            InitActionTable();
            ReflushData();
            txtSearch.TextChanged += TxtSearch_TextChanged;
        }

        private void TxtSearch_TextChanged(object sender, EventArgs e) {
            ReflushData();
        }

        private void Table2_CellClick(object sender, TableClickEventArgs e) {
            var item = e.Record as CksVirtualColumn;
            if (item != null) { //只能有一个主码、一个结果字段
                if (item.IsPrimary) {
                    var items = FieldSource.ToList().FindAll(a => a.Guid != item.Guid && a.IsPrimary);
                    foreach (var cc in items) {
                        cc.IsPrimary = false;
                    }
                }

                if (item.IsResult) {
                    var items = FieldSource.ToList().FindAll(a => a.Guid != item.Guid && a.IsResult);
                    foreach (var cc in items) {
                        cc.IsResult = false;
                    }
                }
            }
            //MessageInfo($"{item.IsPrimary}");
        }

        private void Table1_CellClick(object sender, TableClickEventArgs e) {
            var config = e.Record as CksVirtualTable;
            Context = config;
            if (e.Button == MouseButtons.Left)
                LoadCheckData(Context);
            else if (e.Button == MouseButtons.Right)
                ShowRightButton(table1, config);
        }

        private Action<ContextMenuStripItem> OnClickRightMenu(object data) {
            var db = SqlSugarHelper.MesDB;
            Action<ContextMenuStripItem> action = (menu) => {
                switch (menu.ID) {

                    case "delete":

                        var result = MessageBoxWarn("删除此数据后，相关联的数据将一并删除，确认删除吗？");
                        if (result != DialogResult.OK)
                            return;

                        if (data is CksVirtualTable) {
                            var tableId = (data as CksVirtualTable).Id;
                            //删除采集的数据
                            db.Deleteable<CksCollectedDetails>().Where(a => a.TableId == tableId).ExecuteCommand();
                            db.Deleteable<CksCollected>().Where(a => a.TableId == tableId).ExecuteCommand();
                            //同时删除动作和结构
                            db.Deleteable<CksVirtualColumn>().Where(a => a.TableId == tableId).ExecuteCommand();
                            db.Deleteable<CksPlcActions>().Where(a => a.ActionType == 1 && a.BusinessId == tableId).ExecuteCommand();
                            db.Deleteable<CksVirtualTable>(data).ExecuteCommand();

                            Source.Remove(data as CksVirtualTable);
                        }
                        if (data is CksVirtualColumn) {
                            db.Deleteable<CksVirtualColumn>(data).ExecuteCommand();
                            FieldSource.Remove(data as CksVirtualColumn);
                        }
                        if (data is CksPlcActions) {
                            db.Deleteable<CksPlcActions>(data).ExecuteCommand();
                            ActionsSource.Remove(data as CksPlcActions);
                        }
                        MessageSuccess("删除成功！");
                        break;

                    case "copy":
                        if (data is CksVirtualTable virtualTable) {
                            CksVirtualTable cksVirtualTable = new CksVirtualTable();
                            cksVirtualTable.TableName = virtualTable.TableName;
                            cksVirtualTable.Sequence = virtualTable.Sequence + 1;
                            cksVirtualTable.Notes = virtualTable.Notes;
                            var res = new VirtualTableForm(cksVirtualTable).ShowDialog();
                            if (res == DialogResult.OK) {
                                ReflushData();
                            }
                        }
                        break;
                    default:
                        break;

                }
            };
            return action;
        }

        private void btnAdd_Click(object sender, EventArgs e) {
            var res = new VirtualTableForm().ShowDialog();
            if (res == DialogResult.OK) {
                ReflushData();
            }
        }

        private void btnOpenEdit_Click(object sender, EventArgs e) {
            if (Context == null)
                return;
            var res = new VirtualTableForm(Context).ShowDialog();
            if (res == DialogResult.OK) {
                ReflushData();
            }
        }

        private void btnAddField_Click(object sender, EventArgs e) {
            if (Context == null)
                return;

            int dataCode = 0;
            if (ActionsSource.FirstOrDefault() != null) {
                int count = FieldSource.Count + 1;
                dataCode = ActionsSource.FirstOrDefault().ActionId * 100 + Convert.ToInt32(count.ToString("D2"));
            }

            if (FieldSource.Count == 0) {
                FieldSource.Add(new CksVirtualColumn() { Sequence = 1, ColumnName = "MianCode", IsDisplay = true, IsPrimary = true, Notes = "主产品码", Width = 150, DataId = dataCode });
                dataCode++;
                FieldSource.Add(new CksVirtualColumn() { Sequence = 2, ColumnName = "CycleTime", IsDisplay = true, IsCycleTime = true, Notes = "节拍(s)", Width = 80, DataId = dataCode });
                dataCode++;
                FieldSource.Add(new CksVirtualColumn() { Sequence = 3, ColumnName = "Result", IsDisplay = true, IsResult = true, Notes = "结果", Width = 80, DataId = dataCode });
            } else {
                int sequence = FieldSource.Max(o => o.Sequence) + 1;
                FieldSource.Add(new CksVirtualColumn() { Sequence = sequence, IsDisplay = true, Width = 150, DataId = dataCode });
            }
        }

        private void btnImport_Click(object sender, EventArgs e) {
            if (Context == null) return;
            if (ActionsSource.Count == 0) {
                MessageError("请先配置动作！");
                return;
            }
            var result = MessageBoxWarn("从配置动作点位提取数据，是否继续？");
            if (result == DialogResult.OK) {
                var act = ActionsSource[0];
                var db = SqlSugarHelper.MesDB;
                var items = db.Queryable<CksPlcDataPosition>()
                    .Where(a => a.PlcId == act.PlcId && a.BlockDb == act.ReadDB && a.LinkActionId == act.ActionId)
                    .OrderBy(a => a.DataId).ToList();

                foreach (var item in items) {
                    var one = FieldSource.ToList().Find(a => a.DataId == item.DataId);
                    if (one == null)
                        FieldSource.Add(new CksVirtualColumn() { Notes = item.Remark, IsDisplay = true, Width = 150, ColumnName = item.Description, DataId = item.DataId });
                }
            }
        }

        private void btnSaveField_Click(object sender, EventArgs e) {
            if (Context == null) return;
            var items = FieldSource.ToList().ToList();//.OrderBy(a => a.Sequence)
            if (items.Find(a => a.IsPrimary) == null) {
                MessageError("必须设置主码字段！");
                return;
            }
            //保存字段数据
            var oldColumns = FreeSqlHelper.FreeSql.Select<CksVirtualColumn>().Where(a => a.TableId == Context.Id).ToList();

            var db = SqlSugarHelper.MesDB;
            foreach (var item in items) {
                item.Sequence = table2.SortList().ToList().IndexOf(item) + 1;//重新排序
                item.TableId = Context.Id;
                if (item.Id == 0)
                    db.Insertable(item).ExecuteCommand();
                else {
                    db.Updateable(item).ExecuteCommand();
                }
            }
            LoadColumnData(Context.Id);

            //同步物理表结构
            CreateDBTable(Context, items, oldColumns); //创建表
            MessageSuccess("保存成功！");
        }

        private void btnLoadData_Click(object sender, EventArgs e) {
            if (Context == null) return;
            LoadColumnData(Context.Id);
        }

        private void btnAddAction_Click(object sender, EventArgs e) {
            var count = ActionsSource.Count + 1;
            //var actionCode = Context?.Id == 0 ? 0 : Context.Id * 100 + Convert.ToInt32(count.ToString("D2"));
            var actionCode = 9 * 100 + Convert.ToInt32(count.ToString("D2"));

            var cksPlcActions = new CksPlcActions() { ActionId = actionCode };
            if (ActionsSource.Count == 0) {
                cksPlcActions.ActionKey = "SaveResultRequest";
                cksPlcActions.ActionId = 901;
            }

            ActionsSource.Add(cksPlcActions);
        }

        private void btnSaveActions_Click(object sender, EventArgs e) {
            if (Context == null) return;
            var items = ActionsSource.ToList().OrderBy(a => a.ActionId).ToList();
            var db = SqlSugarHelper.MesDB;
            try {
                foreach (var item in items) {
                    item.BusinessId = Context.Id;
                    item.ActionType = 1;
                    item.Name = "数据采集";

                    if (item.Id == 0)
                        db.Insertable(item).ExecuteCommand();
                    else
                        db.Updateable(item).ExecuteCommand();
                }
                LoadPlcActions(Context.Id);
                MessageSuccess("保存成功！");
            } catch (Exception ex) {
                MessageError("保存失败，可能是动作编号重复！");
            }
        }

        private void btnDeleteAll_Click(object sender, EventArgs e) {
            var deleteList = FieldSource.Where(o => o.IsCheck).ToList();
            if (deleteList.Count() <= 0) {
                MessageError("请选择一行数据！");
                return;
            }
            var result = MessageBoxWarn($"确定删除选中{deleteList.Count()}条数据吗？");
            if (result == DialogResult.OK) {
                var db = SqlSugarHelper.MesDB;
                db.Deleteable<CksVirtualColumn>(deleteList).ExecuteCommand();
                foreach (var item in deleteList) {
                    FieldSource.Remove(item);
                }
            }
        }

        private void btnReflush_Click(object sender, EventArgs e) {
            ReflushData();
        }

        private void checkRowsDragSort_CheckedChanged(object sender, BoolEventArgs e) {
            if (e.Value) table2.Columns.Insert(0, new AntdUI.ColumnSort() { Fixed = true });
            else table2.Columns.RemoveAt(0);
        }
        #endregion


        private void CreateDBTable(CksVirtualTable vtable, List<CksVirtualColumn> vcols, List<CksVirtualColumn> oldColumns) {
            var tableName = vtable.TableName;
            string className = $"Model_{Guid.NewGuid().ToString("N")}";
            List<Attribute> attributes = new List<Attribute>();
            attributes.Add(new TableAttribute { Name = tableName, OldName = "", });
            var mainc = vcols.Find(a => a.IsPrimary);
            if (mainc != null) {
                attributes.Add(new IndexAttribute($"index_{tableName}_{mainc.ColumnName}", $"{mainc.ColumnName} desc"));
            }
            var tableBuilder = FreeSqlHelper.FreeSql.CodeFirst.DynamicEntity(className, attributes.ToArray());

            tableBuilder.Property("Id", typeof(long), new ColumnAttribute() { IsIdentity = true, Position = 1, IsPrimary = true, });
            tableBuilder.Property("PlcId", typeof(int), new ColumnAttribute() { IsNullable = true, Position = 2, });
            tableBuilder.Property("BlockDb", typeof(int), new ColumnAttribute() {IsNullable = true, Position = 3, });
            tableBuilder.Property("CollectBatchCode", typeof(string), new ColumnAttribute() { StringLength = 50, IsNullable = true, Position = 4, });
            foreach (var item in vcols) {
                string oldColumnName = string.Empty;
                var OldCol = oldColumns.Find(a => a.Id == item.Id);
                if (OldCol != null && !OldCol.ColumnName.Equals(item.ColumnName)) {
                    oldColumnName = OldCol.ColumnName;
                }
                if (item.IsPrimary)
                    tableBuilder.Property(item.ColumnName, typeof(string), new ColumnAttribute() { StringLength = 50, IsNullable = true, OldName = oldColumnName }, new DescriptionAttribute(item.Notes));
                else
                    tableBuilder.Property(item.ColumnName, typeof(string), new ColumnAttribute() { StringLength = 50, IsNullable = true, OldName = oldColumnName }, new DescriptionAttribute(item.Notes));
            }

            tableBuilder.Property("StartTime", typeof(DateTime), new ColumnAttribute() { IsNullable = true }, new DescriptionAttribute("开始时间"));//开始时间
            tableBuilder.Property("EndTime", typeof(DateTime), new ColumnAttribute() { IsNullable = true }, new DescriptionAttribute("结束时间"));//结束时间
            tableBuilder.Property("CreateTime", typeof(DateTime), new ColumnAttribute() { IsNullable = true, ServerTime = DateTimeKind.Utc }, new DescriptionAttribute("创建时间"));//创建时间
            tableBuilder.Property("Nullity", typeof(char), new ColumnAttribute() { StringLength = 1 }); //是否禁用，禁用代表无效
            //tableBuilder.Property("Nullity", typeof(bool)); //是否禁用，禁用代表无效
            var table = tableBuilder.Build();

            FreeSqlHelper.FreeSql.CodeFirst.SyncStructure(table.Type); //创建表
        }

    }
}
